<template>
  <div>
    <a-input-number
      :placeholder="placeholder"
      :maxlength="parseInt(maxlength as string)"
      :addonBefore="addonBefore"
      :addonAfter="addonAfter"
      :disabled="disabled"
      :size="size"
      v-model:value="valueRef"
      style="width: 100%"
      @change="handleChange"
      @blur="emit('blur')"
    >
      <template #prefix v-if="prefix">
        <Icon :icon="prefix" />
      </template>
    </a-input-number>
  </div>
</template>

<script lang="ts" setup>
  import { watch, ref, inject, toRaw } from 'vue';
  import { Icon } from '/@/components/Icon';
  import JBC from 'jsbi-calculator';
  import { ComputationalConfig } from '../../Designer/src/types';
  import { sum, mean, max, min } from 'lodash-es';
  import { camelCaseString } from '/@/utils/event/design';

  const { calculator } = JBC;
  const formModel = inject<any>('formModel', null); // 注入表单数据
  const isCustomForm = inject<boolean>('isCustomForm', false);
  const emit = defineEmits(['update:value', 'change', 'blur']);

  const props = defineProps({
    value: Number,
    width: String,
    maxlength: [String, Number],
    placeholder: String,
    addonBefore: String,
    addonAfter: String,
    prefix: String,
    disabled: Boolean,
    computationalConfig: Array as PropType<ComputationalConfig[]>,
    index: Number,
    size: String,
  });

  const valueRef = ref(0);
  watch(
    () => props.value,
    (val) => {
      valueRef.value = val!;
    },
    {
      immediate: true,
    },
  );
  watch(
    () => formModel,
    () => {
      if (!toRaw(props)?.computationalConfig) return;

      let expressionStr = '';

      for (let config of toRaw(props).computationalConfig!) {
        const bindTable = isCustomForm
          ? `${config.bindTable}List`
          : `${camelCaseString(config.bindTable!)}List`;
        const bindField = isCustomForm ? config.bindField : camelCaseString(config.bindField!);

        if (config.type === 'computational' || config.type === 'money-chinese') {
          if (config.isMainForm) {
            //如果是主表字段 直接从formModel 取
            expressionStr += formModel[bindField!] || 0;
          } else {
            //如果是附表 从formModel 取出来 需要进行处理
            if (!formModel[bindTable]) return;
            if (config.computationalMethod) {
              const fieldArray = formModel[bindTable].map(
                (x: { [x: string]: any }) => x[bindField!] || 0,
              );

              switch (config.computationalMethod) {
                case 'sum':
                  expressionStr += `${sum(fieldArray)}`;
                  break;
                case 'mean':
                  expressionStr += `${mean(fieldArray)}`;
                  break;
                case 'min':
                  expressionStr += `${min(fieldArray)}`;
                  break;
                case 'max':
                  expressionStr += `${max(fieldArray)}`;
                  break;
              }
            } else {
              expressionStr +=
                (formModel[bindTable][props.index!] &&
                  formModel[bindTable][props.index!][bindField!]) ||
                0;
            }
          }
        } else {
          expressionStr += `${config.label!}`;
        }
      }

      if (props.computationalConfig!.length > 0) {
        try {
          valueRef.value =
            calculator(`(${expressionStr})`) === 'undefined'
              ? 0
              : Number(calculator(`(${expressionStr})`));
          emit('update:value', valueRef.value);
        } catch {
          console.error('计算式配置错误', expressionStr);
        }
      }
    },
    { deep: true, immediate: true },
  );

  const handleChange = (val) => {
    emit('change');
    emit('update:value', val);
  };
</script>
